package com.sq.util.encrypt;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sq.util.exception.VisualException;

/**
 * @author sq
 *
 */
public class ThreeDes {

    private static Logger log = LoggerFactory.getLogger(ThreeDes.class);

    /**
     * 3DES加密
     * 
     * @param iv
     *            向量
     * @return
     */
    public static byte[] encrypt(byte[] src, byte[] key, byte[] iv) {
        VisualException.isTrue(key.length >= 24, "密钥长度不能少于24位");
        try {
            SecureRandom sr = new SecureRandom();
            DESedeKeySpec dks = new DESedeKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
            SecretKey securekey = keyFactory.generateSecret(dks);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, securekey, ivParameterSpec, sr);
            return cipher.doFinal(src);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 3DES解密
     * 
     * @param iv
     *            向量
     * @return
     */
    public static byte[] decrypt(byte[] src, byte[] key, byte[] iv) {
        VisualException.isTrue(key.length >= 24, "密钥长度不能少于24位");
        try {
            SecureRandom sr = new SecureRandom();
            DESedeKeySpec dks = new DESedeKeySpec(key);
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
            SecretKey securekey = keyFactory.generateSecret(dks);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, securekey, ivParameterSpec, sr);
            return cipher.doFinal(src);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 3DES加密
     * 
     * @param src
     *            加密的数据缓冲区
     * @param key
     *            加密密钥，长度为24字节
     * @return
     */
    public static byte[] encrypt(byte[] src, byte[] key) {
        try {
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(key, "DESede");

            // 加密
            Cipher c1 = Cipher.getInstance("DESede");
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * 3DES解密
     * 
     * @param src
     *            加密的数据缓冲区
     * @param key
     *            加密密钥，长度为24字节
     * @return
     */
    public static byte[] decrypt(byte[] src, byte[] key) {
        try {
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(key, "DESede");

            // 解密
            Cipher c1 = Cipher.getInstance("DESede");
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }
}
